home *** CD-ROM | disk | FTP | other *** search
- // *********************************************************
- // AppBar -- Advanced Menu bar for Windows 95/NT
- // All code Copyright (C) 1995, 1996 by Mike Perham
- // mperham@cs.cornell.edu
- //
- // This code MAY NOT be used for any other program without
- // my permission and is forbidden in any shareware/commercial
- // program. This code is provided for educational use only
- // and there are no guarantees or promises implied. Blah blah
- // *********************************************************
-
- //////////////////////////////////////////////////////////////////////////////////
- // AppBarWin - the Window
- // This file encapsulates all functions that affect what the user sees
- // on the screen and all UI elements.
- //////////
-
- #include "appbar.h"
- #include "globals.h"
-
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[] = __FILE__;
- #define new DEBUG_NEW
- #endif
-
- BEGIN_MESSAGE_MAP(AppBarWin, CWnd)
- //{{AFX_MSG_MAP(AppBarWin)
- ON_WM_ACTIVATE()
- ON_WM_NCMOUSEMOVE()
- ON_WM_NCRBUTTONDOWN()
- // ON_WM_NCLBUTTONDBLCLK()
- ON_WM_SHOWWINDOW()
- ON_WM_TIMECHANGE()
- ON_WM_WINDOWPOSCHANGED()
- ON_WM_TIMER()
- ON_WM_CLOSE()
- ON_MESSAGE(WM_HOTKEY, OnHotKey)
- ON_MESSAGE(WM_DISPLAYCHANGE, OnDisplayChange)
- ON_MESSAGE(WM_POWERBROADCAST, OnPowerBroadcast)
- ON_COMMAND(ID_ABOUT, OnAbout)
- ON_COMMAND(ID_EDIT, OnEdit)
- ON_COMMAND(ID_OPTIONS, OnOptions)
- ON_COMMAND(ID_EXITAPPBAR, OnExit)
- ON_COMMAND_RANGE(101, 40000, OnAppSelect)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
-
- void inline AppBarWin::ab_message(char *msg)
- {
- MessageBox(msg, "AppBar", MB_OK | MB_ICONINFORMATION);
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // AppBarWin message handlers
-
- BOOL AppBarWin::CreateEx(DWORD dwExStyle, LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle,
- int x, int y, int width, int height, HWND ParentWnd, HMENU nID, LPVOID pContext)
- {
- BOOL t = CWnd::CreateEx(dwExStyle, lpszClassName, lpszWindowName, dwStyle,
- x, y, width, height, ParentWnd, nID, pContext);
-
- if (sv.newshell) {
- BOOL ab;
- abd.cbSize = sizeof(APPBARDATA);
- abd.hWnd = m_hWnd;
- abd.uCallbackMessage = NULL;
- abd.uEdge = (uv.bottom ? ABE_BOTTOM : ABE_TOP);
- ab = SHAppBarMessage(ABM_NEW, &abd);
- if (ab && uv.autohide) {
- abd.lParam = TRUE;
- if (!SHAppBarMessage(ABM_SETAUTOHIDEBAR, &abd)) {
- ab_message(ERROR_AUTOHIDING);
- uv.autohide = FALSE;
- }
- } else if (ab) {
- abd.rc.top = 0;
- abd.rc.left = 0;
- abd.rc.right = GetSystemMetrics(SM_CXSCREEN);
- abd.rc.bottom = GetSystemMetrics(SM_CYSCREEN);
- SHAppBarMessage(ABM_QUERYPOS, &abd);
- abd.rc.top = (uv.bottom ? abd.rc.bottom - AB_HEIGHT : abd.rc.top);
- MoveWindow(abd.rc.left, abd.rc.top, AB_WIDTH, AB_HEIGHT, FALSE);
- abd.rc.bottom = abd.rc.top + AB_HEIGHT;
- abd.rc.right = AB_WIDTH;
- SHAppBarMessage(ABM_SETPOS, &abd);
- }
- }
- // Insert applications into menu
- UpdateMenu();
- return t;
- }
-
- void AppBarWin::OnEdit()
- {
- EditDlg ed(this);
- ed.DoModal();
- }
-
- void AppBarWin::OnAbout()
- {
- AboutDlg ad;
- ad.DoModal();
- }
-
- void AppBarWin::OnOptions()
- {
- OptDlg od;
- od.DoModal();
- }
-
- void AppBarWin::OnExit()
- {
- ATOM adam = GlobalFindAtom("AppBar HotKey");
- UnregisterHotKey(m_hWnd, adam);
- GlobalDeleteAtom(adam);
- ab.ExitAppBar(FALSE);
- }
-
- void AppBarWin::OnAppSelect(UINT id)
- {
- app_struct *find = find_appId(id);
- ASSERT(find);
- ab.ExecuteApplication(find);
- }
-
- LONG AppBarWin::OnHotKey(UINT u, LONG l)
- {
- int bitmask;
-
- HideAppBar(FALSE);
- SetForegroundWindow();
- // this is the code for pressing the Alt key down
- // so we can make the menu highlight
- bitmask = 0x00000001 | 38<<16 | 1<<24 | 1<<29;
- PostMessage(WM_SYSKEYDOWN, VK_MENU, bitmask);
- bitmask = 0x00000001 | 38<<16 | 3<<30;
- PostMessage(WM_SYSKEYUP, VK_MENU, bitmask);
- return TRUE;
- }
-
- void AppBarWin::OnActivate(UINT nState, CWnd* pWndOther, BOOL bMinimized)
- {
- CWnd::OnActivate(nState, pWndOther, bMinimized);
- if ((nState == WA_INACTIVE) && uv.autohide) {
- HideAppBar(TRUE);
- KillTimer(HIDE_TIMER);
- }
- if (sv.newshell) {
- abd.cbSize = sizeof(APPBARDATA);
- abd.hWnd = m_hWnd;
- SHAppBarMessage(ABM_ACTIVATE, &abd);
- }
- }
-
- void AppBarWin::OnNcMouseMove(UINT nFlags, CPoint point)
- {
- if (uv.autohide)
- if (!IsShown) {
- POINT pt;
- GetCursorPos(&pt);
- // Don't show AppBar if the mouse moves in the right 10% of the screen.
- // This is so using the max/min buttons doesn't accidently unhide
- // AppBar.
- if (pt.x < sv.width - (int)(sv.width/10))
- HideAppBar(FALSE);
- timer = SetTimer(HIDE_TIMER, 500, NULL);
- } else {
- if (timer)
- KillTimer(HIDE_TIMER);
- timer = SetTimer(HIDE_TIMER, 500, NULL);
- }
- CWnd::OnNcMouseMove(nFlags, point);
- }
- /*
- void AppBarWin::OnNcLButtonDblClk(UINT nHitTest, CPoint pt)
- {
- ATOM adam = GlobalFindAtom("AppBar HotKey");
- UnregisterHotKey(m_hWnd, adam);
- GlobalDeleteAtom(adam);
- ab.ExitAppBar(FALSE);
- }
- */
- // when AppBar is closed via the Task Manager
-
- void AppBarWin::OnClose()
- {
- ATOM adam = GlobalFindAtom("AppBar HotKey");
- UnregisterHotKey(m_hWnd, adam);
- GlobalDeleteAtom(adam);
- ab.ExitAppBar(FALSE);
- }
-
- void AppBarWin::OnNcRButtonDown(UINT nHitTest, CPoint pt)
- {
- CWnd::OnNcRButtonDown(nHitTest, pt);
- CMenu menu;
- VERIFY(menu.LoadMenu(IDR_MENU));
- CMenu *Popup = menu.GetSubMenu(0);
- ASSERT(Popup);
- Popup->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
- pt.x, pt.y, AfxGetMainWnd());
- }
-
- void AppBarWin::OnShowWindow(BOOL bShow, UINT nStatus)
- {
- CWnd::OnShowWindow(bShow, nStatus);
- if (!RegisterHotKey(m_hWnd, GlobalAddAtom("AppBar HotKey"), MOD_ALT | MOD_CONTROL, 0x5A /*z*/))
- if (!RegisterHotKey(m_hWnd, GlobalAddAtom("AppBar HotKey"), MOD_ALT | MOD_CONTROL, 0x41 /*a*/))
- ab_message(ERROR_HOTKEY);
- IsShown = TRUE;
- SyncTime();
- }
-
- void AppBarWin::OnTimeChange()
- {
- ModifyTime();
- CWnd::OnTimeChange();
- }
-
- void AppBarWin::OnTimer(UINT id)
- {
- if (id == TIME_UPDATE)
- ModifyTime();
- else if (id == HIDE_TIMER) {
- if (uv.autohide)
- if (GetActiveWindow() != this) {
- POINT pt;
- GetCursorPos(&pt);
- if (WindowFromPoint(pt) != this) {
- timer = NULL;
- KillTimer(HIDE_TIMER);
- HideAppBar(TRUE);
- }
- }
- } else if (id == SYNC_TIMER) {
- KillTimer(TIME_UPDATE);
- KillTimer(SYNC_TIMER);
- SetTimer(TIME_UPDATE, 10000, NULL);
- ModifyTime();
- }
- CWnd::OnTimer(id);
- }
-
- void AppBarWin::OnWindowPosChanged(WINDOWPOS FAR* lpwndpos)
- {
- CWnd::OnWindowPosChanged(lpwndpos);
- if (sv.newshell) {
- abd.cbSize = sizeof(APPBARDATA);
- abd.hWnd = m_hWnd;
- SHAppBarMessage(ABM_WINDOWPOSCHANGED, &abd);
- }
- }
-
- LONG AppBarWin::OnPowerBroadcast(UINT event, LONG data)
- {
- if (sv.power) {
- SYSTEM_POWER_STATUS sps;
- GetSystemPowerStatus(&sps);
- sv.battery = (sps.ACLineStatus ? FALSE : TRUE);
- ModifyTime();
- }
- return TRUE;
- }
-
- LONG AppBarWin::OnDisplayChange(UINT wParam, LONG lParam)
- {
- if (sv.newshell) {
- sv.width = GetSystemMetrics(SM_CXSCREEN);
- sv.height = GetSystemMetrics(SM_CYSCREEN);
- MoveWindow(0, (uv.bottom ? sv.height - AB_HEIGHT : 0), AB_WIDTH, AB_HEIGHT, TRUE);
- }
- return TRUE;
- }
-
- /////////////////////////////////////////////////////////////////////////////
- // Add-on functions
- ///////////
-
- // Syncs AppBar's timer with the system time
- void AppBarWin::SyncTime(void)
- {
- SYSTEMTIME st;
-
- GetSystemTime(&st);
- // install timer that goes off at next 10 sec interval (10, 20, 30, etc.)
- SetTimer(SYNC_TIMER, ((9-(st.wSecond%10))*1000)+(1000-st.wMilliseconds), NULL);
- }
-
- ///////////////////////////////////////////////////////////////
- // Based on function in Microsoft Systems Journal
- // March 1996 by Jeffrey Richter
- ////
-
- void AppBarWin::Slide(int newy)
- {
- int y, t_start, t_end, t_curr, hide_time;
- RECT start;
-
- hide_time = (IsShown ? 300 : 200);
- GetWindowRect(&start);
- t_start = GetTickCount();
- t_end = t_start + hide_time;
- // Raise the thread priority so that the slide is smooth rather than jerky
- // This is not necessary on a Pentium Pro 200Mhz running NT 4.0 :)
- // SetThreadPriority(ab.m_hThread, THREAD_PRIORITY_ABOVE_NORMAL);
- while ((t_curr = GetTickCount()) < t_end) {
- y = start.top - (start.top - newy) * (int) (t_curr - t_start) / hide_time;
- SetWindowPos(NULL, 0, y, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE);
- UpdateWindow();
- }
- SetWindowPos(NULL, 0, newy, 0, 0, SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOSIZE);
- UpdateWindow();
- // SetThreadPriority(ab.m_hThread, THREAD_PRIORITY_NORMAL);
- }
-
- //////////// hides or shows AppBar, depending on "hide" variable
-
- void AppBarWin::HideAppBar(BOOL hide)
- {
- int newy;
- BOOL drag = TRUE;
-
- if (!hide && IsShown)
- return;
-
- // if you want AppBar to always slide, just comment out this call
- if (sv.newshell)
- SystemParametersInfo(SPI_GETDRAGFULLWINDOWS, 0, &drag, 0);
-
- if (hide) {
- newy = (uv.bottom ? sv.height - 2 : -(AB_HEIGHT - 2));
- IsShown = FALSE;
- drag ? Slide(newy) : SetWindowPos(NULL, 0, newy, 0, 0,
- SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);
- } else {
- newy = (uv.bottom ? sv.height - AB_HEIGHT : 0);
- IsShown = TRUE;
- drag ? Slide(newy) : SetWindowPos(NULL, 0, newy, 0, 0,
- SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOSIZE);
- ModifyTime();
- }
- }
-
- //////////////////////////////////////////////////////////////
-
- void AppBarWin::UpdateMenu(void)
- {
- int a = 1, m = 1; // current app/menu
- app_struct *app;
- menu_struct *menu, *firstapp; // curr menu/first menu with an app
- CMenu hmenu, ab_menu;
- app_list *curapplist, *prevapplist;
-
- kill_applist();
- ab_menu.CreateMenu();
-
- // empty AppBar ???
- if (!glob_menu) {
- applist = NULL;
- SetMenu(&ab_menu);
- ab_menu.Detach();
- DrawMenuBar();
- return;
- }
-
- // find the first non-empty menu
- for (menu = glob_menu, firstapp = NULL; menu; menu = menu->nextmenu)
- if (menu->nextapp) {
- firstapp = menu;
- break;
- }
-
- for (menu = glob_menu; menu; menu = menu->nextmenu) {
- hmenu.CreateMenu();
- for (app = menu->nextapp; app; app = app->nextapp) {
- if (app->separator) // Put in separator
- hmenu.AppendMenu(MF_SEPARATOR, 0, (LPCTSTR)NULL);
- hmenu.AppendMenu(MF_STRING, (m*100 + a), app->appname);
- if (firstapp->nextapp == app) {
- applist = new app_list;
- curapplist = applist;
- } else {
- curapplist = new app_list;
- prevapplist->next = curapplist;
- }
- curapplist->appId = m*100 + a;
- curapplist->app = app;
- curapplist->next = NULL;
- prevapplist = curapplist;
- a++;
- }
- ab_menu.InsertMenu(m, MF_BYPOSITION | MF_POPUP,
- (UINT)hmenu.m_hMenu, menu->menuname);
- hmenu.Detach();
- a = 1;
- m++;
- }
- SetMenu(&ab_menu);
- ab_menu.Detach();
- DrawMenuBar();
- return;
- }
-
- // Update time on menubar every minute
-
- void AppBarWin::ModifyTime(void)
- {
- char string[105] = "";
- char time[20] = "";
- char date[25] = "";
- char mem[10] = "";
- char user[40] = "";
- char batt[20] = "";
- static BOOL played_wav;
- SYSTEM_POWER_STATUS sps;
-
- // if AppBar is hiding, why bother drawing?
- if (IsShown) {
- if (uv.user)
- sprintf(user, "%s ", sv.user);
-
- if (uv.time) {
- GetTimeFormat(LOCALE_SYSTEM_DEFAULT, TIME_NOSECONDS, NULL,
- NULL, time, sizeof(time));
- strcat(time, " ");
- }
-
- if (uv.date) {
- GetDateFormat(LOCALE_SYSTEM_DEFAULT, NULL, NULL, NULL,
- date, sizeof(date));
- strcat(date, " ");
- }
-
- if (uv.memory) {
- MEMORYSTATUS ms;
- GlobalMemoryStatus(&ms);
- sprintf(mem, "%dk ", (int)ms.dwAvailPhys/1024);
- }
-
- if (sv.power)
- if (sv.battery) {
- GetSystemPowerStatus(&sps);
- sprintf(batt, "%d%%", sps.BatteryLifePercent);
- if (sps.BatteryLifePercent == 255) // unknown percentage
- sprintf(batt, "--%%");
- }
-
- // final string to print on AppBar
- sprintf(string, "%s%s%s%s%s", user, time, date, mem, batt);
-
- SIZE s;
- int x,y;
- TEXTMETRIC tm;
- COLORREF c;
- CFont cf, *oldcf;
- NONCLIENTMETRICS ncm;
-
- CWindowDC cdc(this);
- if (sv.newshell) {
- ncm.cbSize = sizeof(NONCLIENTMETRICS);
- SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
- cf.CreateFontIndirect(&(ncm.lfMenuFont));
- oldcf = (CFont *) cdc.SelectObject(&cf);
- }
- c = cdc.SetTextColor(GetSysColor(COLOR_MENUTEXT));
- cdc.SetBkColor(GetSysColor(COLOR_MENU));
- GetTextExtentPoint32(cdc.m_hDC, string, strlen(string), &s);
- x = AB_WIDTH - s.cx - 7;
- cdc.GetTextMetrics(&tm);
- y = (int) ((AB_HEIGHT - tm.tmHeight) / 2);
- // Draw all the stats at (x,y)
- DrawMenuBar();
- cdc.TextOut(x, y, string, strlen(string));
- if (sv.power)
- if (sv.battery) {
- if (sps.BatteryLifePercent > 25)
- cdc.SetTextColor(GREEN);
- else if (sps.BatteryLifePercent > 10)
- cdc.SetTextColor(YELLOW);
- else
- cdc.SetTextColor(RED);
- GetTextExtentPoint32(cdc.m_hDC, batt, strlen(batt), &s);
- x = AB_WIDTH - s.cx - 7;
- cdc.TextOut(x, y, batt, strlen(batt));
- }
- if (sv.newshell) {
- cdc.SelectObject(oldcf);
- cf.DeleteObject();
- }
- cdc.SetTextColor(c);
- } // end if (IsShown)
-
- if (uv.chime) {
- SYSTEMTIME st;
- GetSystemTime(&st);
-
- // if it's the top of the hour and we haven't already played this minute...
- if ((st.wMinute == 0) && (!played_wav)) {
- played_wav = TRUE;
- if (!PlaySound(uv.wavfile, NULL, SND_ASYNC | SND_FILENAME))
- ab_message(ERROR_PLAYING_WAV);
- } else if (st.wMinute == 1)
- played_wav = FALSE;
- }
- }
-
- AppBarWin::AppBarWin()
- {
- CWnd::CWnd();
- }
-
- AppBarWin::~AppBarWin()
- {
- CWnd::~CWnd();
- }
-